<template>
  <div class="events">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>事件管理</span>
          <el-button type="primary" @click="handleAdd">新增事件</el-button>
        </div>
      </template>

      <!-- 搜索栏 -->
      <div class="search-bar">
        <el-form :inline="true" :model="searchForm">
          <el-form-item label="事件名称">
            <el-input v-model="searchForm.name" placeholder="请输入事件名称" clearable />
          </el-form-item>
          <el-form-item label="事件类型">
            <el-select v-model="searchForm.eventType" placeholder="请选择事件类型" clearable>
              <el-option label="HTTP调用" value="HTTP" />
              <el-option label="消息发送" value="MESSAGE" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch">搜索</el-button>
            <el-button @click="handleReset">重置</el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 事件列表 -->
              <el-table :data="eventList" v-loading="loading" style="width: 100%">
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column prop="name" label="事件名称" />
        <el-table-column prop="description" label="描述" show-overflow-tooltip />
        <el-table-column prop="routeId" label="关联路由" width="120">
          <template #default="{ row }">
            <el-tag v-if="row.routeId" type="primary">{{ row.routeId }}</el-tag>
            <span v-else class="text-gray">未关联</span>
          </template>
        </el-table-column>
        <el-table-column prop="eventType" label="事件类型" width="120">
          <template #default="{ row }">
            <el-tag :type="getEventTypeTagType(row.eventType)">
              {{ getEventTypeLabel(row.eventType) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="triggerType" label="触发类型" width="120">
          <template #default="{ row }">
            <el-tag type="info">{{ getTriggerTypeLabel(row.triggerType) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="enabled" label="状态" width="100">
          <template #default="{ row }">
            <el-switch
              v-model="row.enabled"
              @change="handleToggleStatus(row)"
              :loading="row.toggleLoading"
            />
          </template>
        </el-table-column>
        <el-table-column prop="retryCount" label="重试次数" width="100" />
        <el-table-column prop="timeout" label="超时时间(ms)" width="120" />
        <el-table-column prop="createdAt" label="创建时间" width="180">
          <template #default="{ row }">
            {{ formatDateTime(row.createdAt) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="{ row }">
            <el-button size="small" @click="handleEdit(row)">编辑</el-button>
            <el-button size="small" @click="handleTrigger(row)">触发</el-button>
            <el-button size="small" @click="handleViewTriggers(row)">记录</el-button>
            <el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 新增/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="95%"
      top="2vh"
      @close="handleDialogClose"
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="100px"
      >
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="事件名称" prop="name">
              <el-input v-model="form.name" placeholder="请输入事件名称" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="事件类型" prop="eventType">
              <el-select v-model="form.eventType" placeholder="请选择事件类型">
                <el-option label="HTTP调用" value="HTTP" />
                <el-option label="消息发送" value="MESSAGE" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="关联路由" prop="routeId">
              <el-select v-model="form.routeId" placeholder="请选择关联路由" clearable>
                <el-option
                  v-for="route in routeList"
                  :key="route.id"
                  :label="`${route.name} (${route.path})`"
                  :value="route.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="描述" prop="description">
          <el-input
            v-model="form.description"
            type="textarea"
            :rows="3"
            placeholder="请输入事件描述"
          />
        </el-form-item>
        <el-form-item label="触发类型" prop="triggerType">
          <el-select v-model="form.triggerType" placeholder="请选择触发类型">
            <el-option label="Mock调用后触发" value="MOCK_CALL" />
          </el-select>
        </el-form-item>
        <el-form-item label="事件配置" prop="eventConfig" class="event-config-item">
          <div class="config-editor">
            <div class="editor-toolbar">
              <el-button size="small" @click="formatConfig">格式化</el-button>
              <el-button size="small" @click="showConfigHelp">配置说明</el-button>
            </div>
            <div ref="configEditorContainer" class="config-editor-content"></div>
          </div>
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="6">
            <el-form-item label="重试次数" prop="retryCount">
              <el-input-number v-model="form.retryCount" :min="0" :max="10" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="重试间隔(ms)" prop="retryInterval">
              <el-input-number v-model="form.retryInterval" :min="1000" :step="1000" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="超时时间(ms)" prop="timeout">
              <el-input-number v-model="form.timeout" :min="1000" :step="1000" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="是否启用" prop="enabled">
              <el-switch v-model="form.enabled" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit" :loading="submitting">确定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 触发记录对话框 -->
    <el-dialog
      v-model="triggerDialogVisible"
      title="触发记录"
      width="80%"
    >
      <el-table :data="triggerList" v-loading="triggerLoading">
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column prop="triggerTime" label="触发时间" width="180">
          <template #default="{ row }">
            {{ formatDateTime(row.triggerTime) }}
          </template>
        </el-table-column>
        <el-table-column prop="triggerType" label="触发类型" width="120">
          <template #default="{ row }">
            <el-tag type="info">{{ getTriggerTypeLabel(row.triggerType) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="triggerSource" label="触发源" />
        <el-table-column prop="executionStatus" label="执行状态" width="100">
          <template #default="{ row }">
            <el-tag :type="getStatusTagType(row.executionStatus)">
              {{ getStatusLabel(row.executionStatus) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="executionTimeMs" label="执行时间(ms)" width="120" />
        <el-table-column prop="retryCount" label="重试次数" width="100" />
        <el-table-column label="操作" width="120">
          <template #default="{ row }">
            <el-button size="small" @click="handleViewTriggerDetail(row)">详情</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination">
        <el-pagination
          v-model:current-page="triggerCurrentPage"
          v-model:page-size="triggerPageSize"
          :page-sizes="[10, 20, 50]"
          :total="triggerTotal"
          layout="total, sizes, prev, pager, next"
          @size-change="handleTriggerSizeChange"
          @current-change="handleTriggerCurrentChange"
        />
      </div>
    </el-dialog>

    <!-- 触发记录详情对话框 -->
    <el-dialog
      v-model="triggerDetailVisible"
      title="触发记录详情"
      width="60%"
    >
      <div v-if="currentTrigger">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="触发时间">
            {{ formatDateTime(currentTrigger.triggerTime) }}
          </el-descriptions-item>
          <el-descriptions-item label="触发类型">
            {{ getTriggerTypeLabel(currentTrigger.triggerType) }}
          </el-descriptions-item>
          <el-descriptions-item label="触发源">
            {{ currentTrigger.triggerSource }}
          </el-descriptions-item>
          <el-descriptions-item label="执行状态">
            <el-tag :type="getStatusTagType(currentTrigger.executionStatus)">
              {{ getStatusLabel(currentTrigger.executionStatus) }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="执行时间">
            {{ currentTrigger.executionTimeMs }}ms
          </el-descriptions-item>
          <el-descriptions-item label="重试次数">
            {{ currentTrigger.retryCount }}
          </el-descriptions-item>
        </el-descriptions>
        
        <el-divider />
        
        <el-tabs>
          <el-tab-pane label="请求数据">
            <pre v-if="currentTrigger.requestData">{{ formatJson(currentTrigger.requestData) }}</pre>
            <el-empty v-else description="无请求数据" />
          </el-tab-pane>
          <el-tab-pane label="响应数据">
            <pre v-if="currentTrigger.responseData">{{ formatJson(currentTrigger.responseData) }}</pre>
            <el-empty v-else description="无响应数据" />
          </el-tab-pane>
          <el-tab-pane label="错误信息" v-if="currentTrigger.errorMessage">
            <pre>{{ currentTrigger.errorMessage }}</pre>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-dialog>

    <!-- 配置说明对话框 -->
    <el-dialog
      v-model="configHelpVisible"
      title="事件配置说明"
      width="60%"
    >
      <div class="config-help">
        <h4>HTTP事件配置示例：</h4>
        <pre>
{
  "url": "http://example.com/api/webhook?source=${routePath}",
  "method": "POST",
  "headers": {
    "Content-Type": "application/json",
    "Authorization": "Bearer ${env.WEBHOOK_TOKEN}",
    "X-Request-ID": "${timestamp}"
  },
  "body": {
    "event": "mock_call",
    "timestamp": "${timestamp}",
    "routePath": "${routePath}",
    "requestMethod": "${requestMethod}",
    "requestData": "${requestData}",
    "userAgent": "${requestData.headers.User-Agent}",
    "clientIp": "${requestData.ipAddress}"
  },
  "timeout": 30000
}
        </pre>
        
        <h4>可用变量：</h4>
        <ul>
          <li><code>${requestData}</code> - 请求数据</li>
          <li><code>${routePath}</code> - 路由路径</li>
          <li><code>${requestMethod}</code> - 请求方法</li>
          <li><code>${timestamp}</code> - 当前时间戳</li>
          <li><code>${requestData.headers.xxx}</code> - 请求头信息</li>
          <li><code>${requestData.params.xxx}</code> - 请求参数</li>
          <li><code>${requestData.body.xxx}</code> - 请求体数据</li>
          <li><code>${env.xxx}</code> - 环境变量</li>
        </ul>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { ref, reactive, onMounted, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { eventApi, routeApi } from '@/api'
import * as monaco from 'monaco-editor'

export default {
  name: 'Events',
  setup() {
    // 响应式数据
    const loading = ref(false)
    const eventList = ref([])
    const currentPage = ref(1)
    const pageSize = ref(10)
    const total = ref(0)
    
    const searchForm = reactive({
      name: '',
      eventType: ''
    })
    
    const dialogVisible = ref(false)
    const dialogTitle = ref('')
    const submitting = ref(false)
    
    const form = reactive({
      id: null,
      name: '',
      description: '',
      eventType: 'HTTP',
      triggerType: 'MOCK_CALL',
      routeId: null,
      triggerConfig: '',
      eventConfig: '',
      enabled: true,
      retryCount: 0,
      retryInterval: 5000,
      timeout: 30000
    })
    
    const rules = {
      name: [
        { required: true, message: '请输入事件名称', trigger: 'blur' }
      ],
      eventType: [
        { required: true, message: '请选择事件类型', trigger: 'change' }
      ],
      triggerType: [
        { required: true, message: '请选择触发类型', trigger: 'change' }
      ],
      eventConfig: [
        { required: true, message: '请输入事件配置', trigger: 'blur' }
      ]
    }
    
    // 触发记录相关
    const triggerDialogVisible = ref(false)
    const triggerList = ref([])
    const triggerLoading = ref(false)
    const triggerCurrentPage = ref(1)
    const triggerPageSize = ref(10)
    const triggerTotal = ref(0)
    const currentEventId = ref(null)
    
    // 触发记录详情
    const triggerDetailVisible = ref(false)
    const currentTrigger = ref(null)
    
    // 配置编辑器
    const configEditorContainer = ref(null)
    let configEditor = null
    
    // 配置说明
    const configHelpVisible = ref(false)
    
    // 路由列表
    const routeList = ref([])
    
    // 方法
    const loadRouteList = async () => {
      try {
        const response = await eventApi.getRoutes()
        if (response.code === 0) {
          routeList.value = response.data || []
        } else {
          console.error('加载路由列表失败:', response.message)
        }
      } catch (error) {
        console.error('加载路由列表失败:', error)
      }
    }
    
    const loadEventList = async () => {
      loading.value = true
      try {
        const params = {
          page: currentPage.value,
          size: pageSize.value,
          name: searchForm.name || undefined,
          eventType: searchForm.eventType || undefined
        }
        const response = await eventApi.getEventPage(params)
        if (response.code === 0) {
          eventList.value = response.data.records
          total.value = response.data.total
        } else {
          ElMessage.error(response.message || '加载事件列表失败')
        }
      } catch (error) {
        ElMessage.error('加载事件列表失败')
        console.error(error)
      } finally {
        loading.value = false
      }
    }
    
    const handleSearch = () => {
      currentPage.value = 1
      loadEventList()
    }
    
    const handleReset = () => {
      Object.assign(searchForm, {
        name: '',
        eventType: ''
      })
      handleSearch()
    }
    
    const handleSizeChange = (size) => {
      pageSize.value = size
      loadEventList()
    }
    
    const handleCurrentChange = (page) => {
      currentPage.value = page
      loadEventList()
    }
    
    const handleAdd = () => {
      dialogTitle.value = '新增事件'
      Object.assign(form, {
        id: null,
        name: '',
        description: '',
        eventType: 'HTTP',
        triggerType: 'MOCK_CALL',
        triggerConfig: '',
        eventConfig: '{\n  "url": "http://example.com/api/webhook?source=${routePath}",\n  "method": "POST",\n  "headers": {\n    "Content-Type": "application/json",\n    "X-Request-ID": "${timestamp}"\n  },\n  "body": {\n    "event": "mock_call",\n    "timestamp": "${timestamp}",\n    "routePath": "${routePath}",\n    "requestMethod": "${requestMethod}",\n    "requestData": "${requestData}"\n  },\n  "timeout": 30000\n}',
        enabled: true,
        retryCount: 0,
        retryInterval: 5000,
        timeout: 30000
      })
      dialogVisible.value = true
      nextTick(() => {
        initConfigEditor()
      })
    }
    
    const handleEdit = (row) => {
      dialogTitle.value = '编辑事件'
      Object.assign(form, row)
      dialogVisible.value = true
      nextTick(() => {
        initConfigEditor()
      })
    }
    
    const handleDelete = async (row) => {
      try {
        await ElMessageBox.confirm('确定要删除这个事件吗？', '确认删除', {
          type: 'warning'
        })
        const response = await eventApi.deleteEvent(row.id)
        if (response.code === 0) {
          ElMessage.success('删除成功')
          loadEventList()
        } else {
          ElMessage.error(response.message || '删除失败')
        }
      } catch (error) {
        if (error !== 'cancel') {
          ElMessage.error('删除失败')
          console.error(error)
        }
      }
    }
    
    const handleToggleStatus = async (row) => {
      try {
        row.toggleLoading = true
        const response = await eventApi.toggleEvent(row.id, row.enabled)
        if (response.code === 0) {
          ElMessage.success(row.enabled ? '启用成功' : '禁用成功')
        } else {
          row.enabled = !row.enabled // 恢复状态
          ElMessage.error(response.message || '操作失败')
        }
      } catch (error) {
        row.enabled = !row.enabled // 恢复状态
        ElMessage.error('操作失败')
        console.error(error)
      } finally {
        row.toggleLoading = false
      }
    }
    
    const handleTrigger = async (row) => {
      try {
        const response = await eventApi.triggerEvent(row.id)
        if (response.code === 0) {
          ElMessage.success('触发成功')
        } else {
          ElMessage.error(response.message || '触发失败')
        }
      } catch (error) {
        ElMessage.error('触发失败')
        console.error(error)
      }
    }
    
    const handleViewTriggers = async (row) => {
      currentEventId.value = row.id
      triggerDialogVisible.value = true
      triggerCurrentPage.value = 1
      loadTriggerList()
    }
    
    const loadTriggerList = async () => {
      if (!currentEventId.value) return
      
      triggerLoading.value = true
      try {
        const params = {
          page: triggerCurrentPage.value,
          size: triggerPageSize.value
        }
        const response = await eventApi.getEventTriggers(currentEventId.value, params)
        if (response.code === 0) {
          triggerList.value = response.data.records
          triggerTotal.value = response.data.total
        } else {
          ElMessage.error(response.message || '加载触发记录失败')
        }
      } catch (error) {
        ElMessage.error('加载触发记录失败')
        console.error(error)
      } finally {
        triggerLoading.value = false
      }
    }
    
    const handleTriggerSizeChange = (size) => {
      triggerPageSize.value = size
      loadTriggerList()
    }
    
    const handleTriggerCurrentChange = (page) => {
      triggerCurrentPage.value = page
      loadTriggerList()
    }
    
    const handleViewTriggerDetail = (row) => {
      currentTrigger.value = row
      triggerDetailVisible.value = true
    }
    
    const handleSubmit = async () => {
      try {
        submitting.value = true
        form.eventConfig = configEditor.getValue()
        
        if (form.id) {
          const response = await eventApi.updateEvent(form.id, form)
          if (response.code === 0) {
            ElMessage.success('更新成功')
            dialogVisible.value = false
            loadEventList()
          } else {
            ElMessage.error(response.message || '更新失败')
          }
        } else {
          const response = await eventApi.createEvent(form)
          if (response.code === 0) {
            ElMessage.success('创建成功')
            dialogVisible.value = false
            loadEventList()
          } else {
            ElMessage.error(response.message || '创建失败')
          }
        }
      } catch (error) {
        ElMessage.error('操作失败')
        console.error(error)
      } finally {
        submitting.value = false
      }
    }
    
    const handleDialogClose = () => {
      if (configEditor) {
        configEditor.dispose()
        configEditor = null
      }
    }
    
    const initConfigEditor = () => {
      if (configEditor) {
        configEditor.dispose()
      }
      nextTick(() => {
        configEditor = monaco.editor.create(configEditorContainer.value, {
          value: form.eventConfig,
          language: 'json',
          theme: 'vs-dark',
          automaticLayout: true,
          minimap: { enabled: false },
          scrollBeyondLastLine: false,
          fontSize: 14,
          wordWrap: 'on',
          wrappingStrategy: 'advanced',
          lineNumbers: 'on',
          renderLineHighlight: 'all',
          selectOnLineNumbers: true,
          roundedSelection: false,
          readOnly: false,
          cursorStyle: 'line',
          automaticLayout: true,
          scrollbar: {
            vertical: 'visible',
            horizontal: 'visible',
            verticalScrollbarSize: 12,
            horizontalScrollbarSize: 12
          }
        })
        
        // 强制重新布局
        setTimeout(() => {
          if (configEditor) {
            configEditor.layout()
          }
        }, 100)
      })
    }
    
    const formatConfig = () => {
      if (configEditor) {
        try {
          const value = configEditor.getValue()
          const formatted = JSON.stringify(JSON.parse(value), null, 2)
          configEditor.setValue(formatted)
        } catch (error) {
          ElMessage.error('JSON格式错误')
        }
      }
    }
    
    const showConfigHelp = () => {
      configHelpVisible.value = true
    }
    
    // 工具方法
    const getEventTypeLabel = (type) => {
      const map = {
        'HTTP': 'HTTP调用',
        'MESSAGE': '消息发送'
      }
      return map[type] || type
    }
    
    const getEventTypeTagType = (type) => {
      const map = {
        'HTTP': 'primary',
        'MESSAGE': 'success'
      }
      return map[type] || 'info'
    }
    
    const getTriggerTypeLabel = (type) => {
      const map = {
        'MOCK_CALL': 'Mock调用后触发'
      }
      return map[type] || type
    }
    
    const getStatusLabel = (status) => {
      const map = {
        'PENDING': '等待中',
        'RUNNING': '执行中',
        'SUCCESS': '成功',
        'FAILED': '失败'
      }
      return map[status] || status
    }
    
    const getStatusTagType = (status) => {
      const map = {
        'PENDING': 'info',
        'RUNNING': 'warning',
        'SUCCESS': 'success',
        'FAILED': 'danger'
      }
      return map[status] || 'info'
    }
    
    const formatDateTime = (dateTime) => {
      if (!dateTime) return ''
      return new Date(dateTime).toLocaleString()
    }
    
    const formatJson = (jsonStr) => {
      try {
        return JSON.stringify(JSON.parse(jsonStr), null, 2)
      } catch {
        return jsonStr
      }
    }
    
    // 生命周期
    onMounted(() => {
      loadRouteList()
      loadEventList()
    })
    
    return {
      // 数据
      loading,
      eventList,
      currentPage,
      pageSize,
      total,
      searchForm,
      dialogVisible,
      dialogTitle,
      submitting,
      form,
      rules,
      routeList,
      triggerDialogVisible,
      triggerList,
      triggerLoading,
      triggerCurrentPage,
      triggerPageSize,
      triggerTotal,
      triggerDetailVisible,
      currentTrigger,
      configEditorContainer,
      configHelpVisible,
      
      // 方法
      handleSearch,
      handleReset,
      handleSizeChange,
      handleCurrentChange,
      handleAdd,
      handleEdit,
      handleDelete,
      handleToggleStatus,
      handleTrigger,
      handleViewTriggers,
      handleTriggerSizeChange,
      handleTriggerCurrentChange,
      handleViewTriggerDetail,
      handleSubmit,
      handleDialogClose,
      formatConfig,
      showConfigHelp,
      
      // 工具方法
      getEventTypeLabel,
      getEventTypeTagType,
      getTriggerTypeLabel,
      getStatusLabel,
      getStatusTagType,
      formatDateTime,
      formatJson
    }
  }
}
</script>

<style scoped>
.events {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.search-bar {
  margin-bottom: 20px;
}

.pagination {
  margin-top: 20px;
  text-align: right;
}

.config-editor {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  width: 100%;
}

.editor-toolbar {
  padding: 8px 12px;
  border-bottom: 1px solid #dcdfe6;
  background-color: #f5f7fa;
  display: flex;
  gap: 8px;
}

.config-editor-content {
  height: 400px;
  min-height: 300px;
  width: 100%;
}

.event-config-item .el-form-item__content {
  width: 100%;
}

.event-config-item .el-form-item__label {
  width: 100px !important;
  text-align: left;
}

.event-config-item {
  margin-bottom: 20px;
}

.dialog-footer {
  text-align: right;
  padding-top: 10px;
}

.config-help {
  line-height: 1.6;
}

.config-help pre {
  background-color: #f5f7fa;
  padding: 12px;
  border-radius: 4px;
  overflow-x: auto;
}

.config-help ul {
  margin: 10px 0;
  padding-left: 20px;
}

.config-help code {
  background-color: #f5f7fa;
  padding: 2px 4px;
  border-radius: 2px;
  font-family: monospace;
}
</style> 